20260821-linuxkm-WC_SVR_USE_NATIVE_REG_BUFS - #11240
Conversation
…er-CPU
native vector register save buffers, serving hardirq and softirq contexts
where kernel_fpu_begin() is unusable.
previously these contexts were refused (WC_ACCEL_INHIBIT_E): hardirq
outright, softirq whenever !may_use_simd() (pre-6.15, a softirq
interrupting a foreign kernel_fpu section). an exact save/compute/restore
cycle is invisible to the interrupted context and to kernel FPU
bookkeeping, and run-to-completion freezes the blocking condition beneath
the section, so both classes are natively serviceable.
- per-CPU {softirq, hardirq} state, each {depth, pin_preempt, save_area};
xsave64/xrstor64 with RFBM 0xe7 & XCR0 (fxsave64 fallback), plain XSAVE
only; feature detection by direct CPUID/XGETBV, independent of kernel
cpufeature machinery.
- recursion is a per-(CPU, class) depth count -- save on the 0->1 edge,
restore on 1->0; softirq sections hold preempt_disable() (load-bearing
on PREEMPT_RT).
- hardirq serves plain saves; softirq serves plain and _MAYBE_INHIBIT
(its legacy short-circuit is bypassed when native is ready); _INHIBIT,
hardirq _MAYBE, and NMI keep refusal semantics; task context is
untouched.
- wc_svr_native_init() activates in place from
wc_linuxkm_allocate_svr_states() in any context but NMI -- the FIPS
pre-Init lazy allocation arrives inside the outermost save's own
bracket, and wolfCrypt_Init() has been observed with irqs disabled. a
self-bracketed register round-trip selftest gates wc_svr_native_ready;
on any failure the long-standing refusal semantics remain fully in
force.
- wc_linuxkm_svr_native_is_ready(): runtime readiness accessor for policy
decisions elsewhere (e.g. the FIPS<v7 default-bank NO_VECTOR_OPS pin).
- WOLFSSL_LINUXKM_VERBOSE_DEBUG: split the softirq WC_ACCEL_INHIBIT_E
counter into per-class counters (softirq, hardirq, NMI, other),
reported at module shutdown.
in non-VERBOSE builds with WC_SVR_DONT_USE_NATIVE_REG_BUFS (or in non-SVR
builds), generated object code is byte-identical to the previous revision.
|
|
retest this please |
|
retest this please |
kaleb-himes
left a comment
There was a problem hiding this comment.
Passed the battery of tests thrown at it. Sha 256 was a little slow under load but I think that will get cleaned up by the coming ASM fixes so not holding the PR up over it.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11240
Scan targets checked: linuxkm-bugs, linuxkm-src, wolfcrypt-bugs, wolfcrypt-rs-bugs, wolfcrypt-src
Findings: 6
6 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
|
|
||
| #if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) | ||
| #if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \ | ||
| !defined(WC_SVR_USE_NATIVE_REG_BUFS) && \ |
There was a problem hiding this comment.
FIPSv7 default-bank NO_VECTOR_OPS pin gated on compile-time WC_SVR_USE_NATIVE_REG_BUFS instead of runtime readiness · Logic errors
The pin is compiled out whenever WC_SVR_USE_NATIVE_REG_BUFS is built in, but native service can fail at runtime (no XSAVE/FXSR, allocation failure, selftest failure). On such boots linuxkm_get_drbg() still sets WC_RNG_BANK_FLAG_NO_VECTOR_OPS only in non-blockable contexts, so a FIPS v5/v6 wc_Sha256 DRBG instance alternates between asm and C mid-object — the exact breakage the pin prevents. linuxkm_get_drbg() at line 2211 already uses the runtime accessor.
Related known finding #7893 (similar but distinct): Both involve Linux DRBG default-bank startup state, but the candidate faults in wc_linuxkm_rng_bank_init's vector-operation flag selection when native register buffers are unavailable at runtime; #7893 faults in wc_linuxkm_drbg_startup's missing rollback after later failures. The root causes and corrective patches are distinct.
Fix: Keep the block compiled under WC_SVR_USE_NATIVE_REG_BUFS and gate the pin at runtime with !wc_linuxkm_svr_native_is_ready(), mirroring linuxkm_get_drbg().
| #if defined(WC_SVR_DONT_USE_NATIVE_REG_BUFS) | ||
| #undef WC_SVR_USE_NATIVE_REG_BUFS | ||
| #elif defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WC_SVR_USE_NATIVE_REG_BUFS) | ||
| #define WC_SVR_USE_NATIVE_REG_BUFS |
There was a problem hiding this comment.
WC_SVR_USE_NATIVE_REG_BUFS is auto-defined on non-x86, but its implementation and declaration are CONFIG_X86-only · LKCAPI interface correctness
The auto-define keys only on WOLFSSL_USE_SAVE_VECTOR_REGISTERS, which is also set for the ARM path at line 258. wc_linuxkm_svr_native_is_ready() is declared only inside the defined(CONFIG_X86) block at line 746 and defined only in x86_vector_register_glue.c, so the #ifdef WC_SVR_USE_NATIVE_REG_BUFS call at lkcapi_sha_glue.c:2211 has no declaration or symbol on ARM linuxkm builds.
Fix: Add && defined(CONFIG_X86) to the #elif condition that auto-defines WC_SVR_USE_NATIVE_REG_BUFS.
|
|
||
| #if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) | ||
| #if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \ | ||
| !defined(WC_SVR_USE_NATIVE_REG_BUFS) && \ |
There was a problem hiding this comment.
FIPS7 default-bank NO_VECTOR_OPS pin is dropped on a compile-time macro rather than runtime native readiness · Cryptographic correctness
WC_SVR_USE_NATIVE_REG_BUFS only means the native save path is compiled in; wc_svr_native_ready stays 0 when the CPU lacks XSAVE/FXSR, the GFP_ATOMIC save-buffer allocation fails, or wc_svr_native_selftest() fails. In those builds the bank-level pin is gone while native never serves, so bankref checkouts via wc_local_rng_bank_checkout_for_bankref() (which sets no per-call NO_VECTOR_OPS) run unpinned. The sibling site linuxkm_get_drbg() at line 2211 correctly uses the runtime accessor.
Related known finding #7929 (similar but distinct): Both affect LinuxKM DRBG/default-bank initialization in lkcapi_sha_glue.c and can leave default-RNG behavior unsafe or inconsistent. However, #7929 faults after DRBG registration by omitting rollback on later startup failures, while this finding selects vector-operation pinning from compile-time availability instead of runtime native readiness; the operations, root causes, and patches differ.
Fix: Keep the FIPS<7 branch compiled in and gate the pin at runtime on !wc_linuxkm_svr_native_is_ready() instead of the build-time macro.
|
|
||
| #if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) | ||
| #if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \ | ||
| !defined(WC_SVR_USE_NATIVE_REG_BUFS) && \ |
There was a problem hiding this comment.
FIPSv7 NO_VECTOR_OPS pin is gated at compile time instead of on runtime native readiness · Logic errors
The WC_RNG_BANK_FLAG_NO_VECTOR_OPS pin is now suppressed whenever WC_SVR_USE_NATIVE_REG_BUFS is merely compiled in. Native service can fail to come up at runtime (no XSAVE/FXSR, allocation failure, selftest failure in wc_svr_native_init()), and the pin is then dropped anyway, reintroducing mid-object asm/C switching that FIPS v5/v6 SHA-2 cannot survive. linuxkm_get_drbg() in the same file uses the runtime accessor.
Fix: Keep the #if on WOLFSSL_USE_SAVE_VECTOR_REGISTERS && HAVE_FIPS && FIPS_VERSION3_LT(7,0,0) and add a runtime !wc_linuxkm_svr_native_is_ready() condition to the if.
| return 1; | ||
| } | ||
| #endif /* WC_SVR_USE_NATIVE_REG_BUFS */ | ||
| #ifdef DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO |
There was a problem hiding this comment.
New DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO macro not registered in .wolfssl_known_macro_extras · Incorrect macro expansion
DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO is introduced at lines 505 and 607 but is defined nowhere in the tree. Its siblings DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_ON/OFF are listed in .wolfssl_known_macro_extras:255-256; this PR adds CONFIG_X86_64 and WC_SVR_DONT_USE_NATIVE_REG_BUFS there but omits this one, so the unknown-macro check flags it.
Fix: Add DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO to .wolfssl_known_macro_extras.
|
|
||
| #if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0) | ||
| #if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \ | ||
| !defined(WC_SVR_USE_NATIVE_REG_BUFS) && \ |
There was a problem hiding this comment.
FIPS7 default-bank NO_VECTOR_OPS pin is dropped at compile time instead of on runtime native readiness · Preprocessor-conditional security bypass
The pin is gated on !defined(WC_SVR_USE_NATIVE_REG_BUFS), which the header defines for every SVR build. When wc_svr_native_init() bails out (no XSAVE/FXSR, allocation failure, or selftest mismatch at x86_vector_register_glue.c:1579), wc_svr_native_ready stays 0 and the old refusal semantics remain in force, yet the pin is already gone. linuxkm_get_drbg() at line 2211 makes the identical policy decision via the runtime accessor.
Related known finding #7929 (similar but distinct): Both affect LinuxKM DRBG/default-bank startup in the same file, but the candidate faults in wc_linuxkm_rng_bank_init's NO_VECTOR_OPS policy gate when native vector readiness fails; #7929 faults in wc_linuxkm_drbg_startup rollback after later registration failures. Their root causes and corrective patches are different.
Fix: Gate the pin on wc_linuxkm_svr_native_is_ready() at runtime, as linuxkm_get_drbg() does, rather than on the compile-time macro.
linuxkm/x86_vector_register_glue.c: addWC_SVR_USE_NATIVE_REG_BUFS: per-CPUnative vector register save buffers, serving hardirq and softirq contexts
where
kernel_fpu_begin()is unusable.previously these contexts were refused (
WC_ACCEL_INHIBIT_E): hardirqoutright, softirq whenever !
may_use_simd()(pre-6.15, a softirqinterrupting a foreign kernel_fpu section). an exact save/compute/restore
cycle is invisible to the interrupted context and to kernel FPU
bookkeeping, and run-to-completion freezes the blocking condition beneath
the section, so both classes are natively serviceable.
per-CPU {softirq, hardirq} state, each {depth, pin_preempt, save_area};
xsave64/xrstor64 with RFBM 0xe7 & XCR0 (fxsave64 fallback), plain XSAVE
only; feature detection by direct CPUID/XGETBV, independent of kernel
cpufeature machinery.
recursion is a per-(CPU, class) depth count -- save on the 0->1 edge,
restore on 1->0; softirq sections hold
preempt_disable()(load-bearingon
PREEMPT_RT).hardirq serves plain saves; softirq serves plain and _
MAYBE_INHIBIT(its legacy short-circuit is bypassed when native is ready); _INHIBIT,
hardirq _MAYBE, and NMI keep refusal semantics; task context is
untouched.
wc_svr_native_init()activates in place fromwc_linuxkm_allocate_svr_states()in any context but NMI -- the FIPSpre-Init lazy allocation arrives inside the outermost save's own
bracket, and
wolfCrypt_Init()has been observed with irqs disabled. aself-bracketed register round-trip selftest gates wc_svr_native_ready;
on any failure the long-standing refusal semantics remain fully in
force.
wc_linuxkm_svr_native_is_ready(): runtime readiness accessor for policydecisions elsewhere (e.g. the FIPS<v7 default-bank
NO_VECTOR_OPSpin).WOLFSSL_LINUXKM_VERBOSE_DEBUG: split the softirqWC_ACCEL_INHIBIT_Ecounter into per-class counters (softirq, hardirq, NMI, other),
reported at module shutdown.
in non-VERBOSE builds with
WC_SVR_DONT_USE_NATIVE_REG_BUFS(or in non-SVRbuilds), generated object code is byte-identical to the previous revision.
also add
linuxkm/simd_hammer/, a stress testing tool for kernel FPU/SIMD context handling.tested with